﻿#ifndef _TASKTIMER_H
#define _TASKTIMER_H

#include <map>
#include <mutex>
#include <functional>
#include <memory>
#include <thread>
#include <atomic>
#include "Event.h"

/* timeout task processing */

class Event;

struct TaskData
{
    uint64_t                            m_taskid;

    std::shared_ptr<unsigned char>      m_data;
    int                                 m_data_len;

    uint64_t                            m_status;

    TaskData();
    ~TaskData();
};
typedef std::shared_ptr<TaskData> TaskDataPtr;

struct cmp
{
    bool operator()(const struct timeval& v1, const struct timeval& v2) const
    {
        if (v1.tv_sec != v2.tv_sec) return v1.tv_sec < v2.tv_sec;

        if (v1.tv_usec != v2.tv_usec) return v1.tv_usec < v2.tv_usec;

        return false;
    }
};

struct TimePacker 
{
    std::weak_ptr<TaskData> m_param;
    std::function<void(std::weak_ptr<TaskData>)> m_func;

    TimePacker(std::weak_ptr<TaskData> param, std::function<void(std::weak_ptr<TaskData>)> func) :
        m_param(param),
        m_func(func)
    {

    }

    ~TimePacker()
    {

    }
};
typedef std::shared_ptr<TimePacker> TimePackerPtr;

class TaskTimer : public Event
{
public:
    explicit TaskTimer(uint32_t baseid);
    ~TaskTimer();

    TaskDataPtr GetTask(uint64_t taskid);

    uint64_t  GetDataId();
    
    int AddTask(std::shared_ptr<TaskData> m_param);

    int AddTask(
        long long msecond, std::shared_ptr<TaskData> param, std::function<void(std::weak_ptr<TaskData>)> func = NULL
    );
    int DeleteTask(uint64_t taskid);

    virtual void CycleTask(); /* 超时事件 */
private:
    
    int AddTask(
        long long msecond, std::function<void(std::weak_ptr<TaskData>)> m_func, std::weak_ptr<TaskData> param
    );

    TaskTimer(const TaskTimer& other) = delete;
    TaskTimer& operator=(const TaskTimer& other) = delete;
private:

    std::atomic<uint32_t>            m_data_id;
    uint64_t                         m_unique_id;

    std::mutex            m_spin_lock;
    
    std::map<struct timeval, TimePackerPtr, cmp>  m_TimeTask;
    std::map<uint64_t, TaskDataPtr>      m_task_list;
};

#endif  //_TASKTIMER_H